		TITLE	CVTYPCON - Copyright (C) SLR Systems 1994

		INCLUDE	MACROS

if	fg_cvpack

		INCLUDE	CVTYPES

		PUBLIC	CONVERT_CV_LTYPE_GTYPE_A,CIRC_HELP,NEW_DERIV_BLK_INIT,FLUSH_DERIVATIVES,FIRST_DERIV_BLK


		.DATA

		EXTERNDEF	DEBUG_TYPES_SELECTED:BYTE,TYPE_COLLISION_TID:BYTE

		EXTERNDEF	CV_GTYPE_HASH:DWORD,CV_GTYPE_HASH_LOG:DWORD,TYPE_COLLISION_COUNT:DWORD,TYPE_COLLISION_MAX:DWORD

		EXTERNDEF	CV_LTYPE_GARRAY:STD_PTR_S,CV_GTYPE_GARRAY:STD_PTR_S

		EXTERNDEF	CASE_STRING_COMPARE:DWORD


		.CODE	CVPACK_TEXT

		EXTERNDEF	WARN_RET:PROC,ERR_RET:PROC,_err_abort:proc,CV_GTYPE_POOL_GET:PROC,_get_omf_name_length_routine:proc
		EXTERNDEF	CV_LTYPE_POOL_GET:PROC,GET_NEW_LOG_BLK:PROC,SKIP_LEAF_SICXAX:PROC,ERR_HEX_ABORT:PROC
		EXTERNDEF	OPTI_HASH32:PROC,OPTI_HASH32_CASE:PROC,ERR_HEX_RET:PROC

		EXTERNDEF	TYPE_PUNT_ERR:ABS,MEMBER_PUNT_ERR:ABS,CLASS_PUNT_ERR:ABS,TYPE_PUNT_SUCCESS_ERR:ABS
		EXTERNDEF	CLASS_ZERO_ERR:ABS,FIXED_SPEC_ERR:ABS,CANNOT_FIX_SPEC_ERR:ABS,BAD_TYPEINDEX_ERR:ABS
		EXTERNDEF	CVP_CIRC_NO_CSUE_ERR:ABS,CVP_GTYPES_64K_ERR:ABS


CONVERT_CV_LTYPE_GTYPE_A	PROC	NEAR
		;
		;EAX IS LOCAL TYPE INDEX
		;
		;RETURN EAX IS GLOBAL TYPE INDEX
		;
		;NOT CALLED UNLESS A NON-PRIMITIVE TYPE
		;
		;NEXT, ITS PROBABLY ALREADY DEFINED
		;
		MOV	ECX,CV_LTYPE_GARRAY._STD_LIMIT
		SUB	EAX,1000H-1

		CMP	ECX,EAX
		JB	L12$

		CONVERT	EDX,EAX,CV_LTYPE_GARRAY
		ASSUME	EDX:PTR CV_LTYPE_STRUCT

		MOV	ECX,EAX
		MOV	AL,[EDX]._CV_LTYPE_FLAGS

		TEST	AL,MASK CV_LTYPE_INSTALLED
		JZ	L2$

		MOV	EAX,[EDX]._CV_LTYPE_GTYPE
		OR	EDX,EDX

		RET

L12$:
		BITT	CV_TYPES_VALID
		JZ	L13$

		LEA	ECX,[EAX+1000H-1]
		MOV	AX,BAD_TYPEINDEX_ERR

		CALL	ERR_HEX_RET
L13$:
		XOR	EAX,EAX

		RET

L15$:
		;
		;WE HAVE A CIRCULAR SITUATION
		;
		;UPDATE CIRCULAR_BASE AND CIRCULAR_INDEX IF NECESSARY
		;
		TEST	AL,MASK CV_LTYPE_CSUE
		JZ	L16$

		MOV	CIRCULAR_CSUE,ECX
L16$:
		MOV	EAX,[EDX]._CV_LTYPE_GTYPE

		TEST	EAX,EAX
		JZ	L165$

		CONVERT	EDX,EAX,CV_LTYPE_GARRAY

		MOV	ECX,EAX
		JMP	L16$

L165$:
		MOV	EAX,[EDX]._CV_LTYPE_NEST_LEVEL	;NEST LEVEL FOR THIS TYPE
		MOV	EDX,CIRCULAR_BASE

		CMP	EDX,EAX
		JBE	L17$

		MOV	CIRCULAR_BASE,EAX	;WON'T DO CIRC_HELP UNTIL I RETURN TO
		MOV	CIRCULAR_INDEX,ECX	;THIS MATCHING BASE AND INDEX
L17$:
		SUB	EAX,-1			;FLAG CIRCULAR REFERENCE

		RET


L2$:
		;
		;IF IT IS ALREADY BEING DEFINED, WE'VE GOT A CIRCULAR PROBLEM...
		;
		TEST	AL,MASK CV_LTYPE_DEFINING
		JNZ	L15$
		;
		;OK, CONVERT ANY TYPES I REFERENCE
		;
		PUSH	ESI
		MOV	ESI,EDX
		ASSUME	ESI:PTR CV_LTYPE_STRUCT

		PUSH	EBX
		MOV	EBX,ECX

;		MOV	DX,[ESI]._CV_LTYPE_ILEAF	;INTERNAL LEAF ID
		MOV	EDX,DPTR [ESI]._CV_LTYPE_LENGTH
		OR	AL,MASK CV_LTYPE_DEFINING
		ASSUME	EDX:NOTHING

		SHR	EDX,16
		MOV	[ESI]._CV_LTYPE_FLAGS,AL
		;
		;SET UP BASIS FOR A NON-CIRCULAR SEARCH
		;
		MOV	EAX,CIRCULAR_BASE	;SAVE OLD BASE(NEST_LEVEL) AND INDEX
		MOV	ECX,CIRCULAR_INDEX

		PUSHM	EAX,ECX

		MOV	ECX,CIRCULAR_CSUE	;SAVE OLD CSUE
		XOR	EAX,EAX

		MOV	[ESI]._CV_LTYPE_GTYPE,EAX
		MOV	CIRCULAR_INDEX,EAX

		MOV	CIRCULAR_CSUE,EAX
		DEC	EAX

		MOV	CIRCULAR_BASE,EAX
		MOV	EAX,CONVERT_NEST_LEVEL

		PUSH	ECX
		INC	EAX

		MOV	CONVERT_NEST_LEVEL,EAX
		MOV	[ESI]._CV_LTYPE_NEST_LEVEL,EAX	;NEST LEVEL I FIRST TOUCHED THIS GUY
		;
		;
		;
		CALL	LTYPE_DEFINES[EDX*4]	;CONVERT ANY TYPES I TOUCH

		MOV	EAX,CIRCULAR_BASE
		MOV	ECX,CONVERT_NEST_LEVEL

		OR	EAX,EAX
		JNS	L7$			;NO-SIGN MEANS WE HAVE A CIRCULAR PROBLEM
		;
		;HOPEFULLY MOST ARE THIS KIND...
		;
		DEC	ECX
		POP	EAX

		MOV	CONVERT_NEST_LEVEL,ECX
		MOV	CIRCULAR_CSUE,EAX	;RESTORE OLD CSUE

		POP	ECX
		MOV	AL,[ESI]._CV_LTYPE_FLAGS

		MOV	CIRCULAR_INDEX,ECX	;RESTORE OLD INDEX
		AND	AL,NOT MASK CV_LTYPE_DEFINING

		POP	ECX
		OR	AL,MASK CV_LTYPE_INSTALLED

		MOV	CIRCULAR_BASE,ECX	;RESTORE OLD BASE
		MOV	[ESI]._CV_LTYPE_FLAGS,AL

		TEST	AL,MASK CV_LTYPE_CSUE
		JNZ	L3$

		MOV	EAX,DPTR [ESI]._CV_LTYPE_LENGTH	;EXCLUDING LENGTH FIELD ITSELF
		LEA	ECX,[ESI]._CV_LTYPE_LENGTH

		AND	EAX,0FFFFH

		ADD	EAX,2
		CALL	OPTI_HASH32_CASE		;RETURNS HASH IN EAX

		MOV	[ESI]._CV_LTYPE_HASH,EAX
		CALL	INSTALL_LTYPE_GTYPE	;DO NORMAL INSTALL

		POP	EBX
		MOV	[ESI]._CV_LTYPE_GTYPE,EAX

		POP	ESI
		OR	EAX,EAX

		RET

L3$:
		MOV	EAX,[ESI]._CV_LTYPE_HASH
		CALL	INSTALL_CSUE_GTYPE

		POP	EBX
		MOV	[ESI]._CV_LTYPE_GTYPE,EAX

		POP	ESI
		OR	EAX,EAX

		RET

L7$:
		;
		;CIRCULAR IN PROGRESS...
		;
		CMP	ECX,EAX		;ECX IS CONVERT_NEST_LEVEL
		JNZ	L71$		;EAX IS CIRCULAR_BASE

		CMP	CIRCULAR_INDEX,EBX	;AM I THE INDEX BEING WAITED ON?
		JZ	L8$
L71$:
		;
		;NO, NOT REALLY DONE WITH THIS CIRCULAR MESS.
		;
		POP	EDX		;OLD CSUE
		MOV	AL,[ESI]._CV_LTYPE_FLAGS
		;
		;MAKE SURE CSUE IS DEFINED IF POSSIBLE
		;
		TEST	EDX,EDX		;KEEP OLD IF THERE
		JNZ	L72$

		TEST	AL,MASK CV_LTYPE_CSUE	;OTHERWISE, USE ME IF I'M ONE
		JZ	L73$

		MOV	CIRCULAR_CSUE,EBX
		JMP	L73$

L72$:
		MOV	CIRCULAR_CSUE,EDX
L73$:
		POP	EDX
		DEC	ECX

		POP	EAX
		MOV	CONVERT_NEST_LEVEL,ECX

		CMP	CIRCULAR_BASE,EAX	;RESTORE OLD BASE AND INDEX IF OLD BASE IS LOWER OR EQUAL
		JB	L74$			;(KEEP NEW BASE & INDEX IF NEW BASE IS LOWER)

		MOV	CIRCULAR_BASE,EAX
		MOV	CIRCULAR_INDEX,EDX

		SUB	ECX,-1

L74$:
		MOV	EAX,CIRCULAR_BASE
		MOV	EDX,CIRCULAR_INDEX

		POP	EBX
		MOV	[ESI]._CV_LTYPE_GTYPE,EDX

		MOV	[ESI]._CV_LTYPE_NEST_LEVEL,EAX	;LOWEST NEST LEVEL ASSOCIATED WITH ME...
		POP	ESI

		RET				;CARRY SET!

L8$:
		;
		;OK, I AM CIRCULAR BASE...
		;
		;TBD...
		;
		MOV	EDX,((NOT MASK CV_LTYPE_DEFINING)SHL 8)+ MASK CV_LTYPE_DEFINING2
		CALL	CIRC_HELP	;DEFINE THESE GUYS SOME OTHER WAY...
		;
		;OK, THIS GUY IS DEFINED...
		;
		POP	EAX
		MOV	ECX,CONVERT_NEST_LEVEL

		POP	EDX
		DEC	ECX

		MOV	CIRCULAR_CSUE,EAX
		MOV	CONVERT_NEST_LEVEL,ECX

		POP	EAX
		MOV	CIRCULAR_INDEX,EDX

		MOV	CIRCULAR_BASE,EAX
		MOV	EAX,[ESI]._CV_LTYPE_GTYPE

		POPM	EBX,ESI

		OR	EAX,EAX		;CLEAR CARRY

		RET

CONVERT_CV_LTYPE_GTYPE_A	ENDP


INSTALL_LTYPE_GTYPE	PROC	NEAR
		;
		;ESI (EBX) IS LTYPE_STRUCTURE, RETURN EQUIVALENT GLOBAL TYPE IN EAX
		;EAX IS HASH
		;
		PUSH	EDI
		XOR	EDX,EDX

		MOV	ECX,CV_GTYPE_HASH_LOG

		HASHDIV	CV_GTYPE_HASH

		LEA	EDI,[ECX+EDX*4-CV_GTYPE_STRUCT._CV_GTYPE_NEXT_HASH]
		MOV	EDX,[ECX+EDX*4]
L2$:
		TEST	EDX,EDX
		JZ	L4$

		CONVERT	EDI,EDX,CV_GTYPE_GARRAY
		ASSUME	EDI:PTR CV_GTYPE_STRUCT

		MOV	EAX,[ESI]._CV_LTYPE_HASH
		MOV	ECX,[EDI]._CV_GTYPE_HASH

		CMP	EAX,ECX
		JNZ	L3$

		MOV	ECX,DPTR [ESI]._CV_LTYPE_LENGTH
		MOV	EAX,ESI

		AND	ECX,0FFFFH
		LEA	ESI,[ESI]._CV_LTYPE_LENGTH

		ADD	ECX,5
		PUSH	EDI

		SHR	ECX,2
		LEA	EDI,[EDI]._CV_GTYPE_LENGTH

		REPE	CMPSD

		POP	EDI
		JZ	L5$

		MOV	ESI,EAX
L3$:
		MOV	EDX,[EDI]._CV_GTYPE_NEXT_HASH
		JMP	L2$

L4$:
		;
		;INSTALL NEW COPY
		;
		;EDI IS PLACE TO STORE INDEX # OF NEW TYPE
		;
		;HOW MUCH SPACE DO I NEED TO ALLOCATE?
		;
		MOV	EAX,DPTR [ESI]._CV_LTYPE_LENGTH

		AND	EAX,0FFFFH

		ADD	EAX,CV_GTYPE_STRUCT._CV_GTYPE_ILEAF
		CALL	CV_GTYPE_POOL_GET

		MOV	ECX,EAX
		INSTALL_POINTER_GINDEX	CV_GTYPE_GARRAY
		MOV	[EDI]._CV_GTYPE_NEXT_HASH,EAX

		MOV	EDI,ECX
		MOV	EDX,EAX

		XOR	EAX,EAX
		MOV	ECX,CV_GTYPE_STRUCT._CV_GTYPE_HASH/4

		REP	STOSD

		MOV	ECX,DPTR [ESI]._CV_LTYPE_LENGTH
		MOV	EAX,ESI

		AND	ECX,0FFFFH
		LEA	ESI,[ESI]._CV_LTYPE_HASH

		ADD	ECX,9			;HASH, LENGTH, MOVING DWORDS...

		SHR	ECX,2

		REP	MOVSD
L5$:
		POP	EDI
		MOV	ESI,EAX

		LEA	EAX,[EDX+1000H-1]

		RET		;RETURNS ESI IS ORIGINAL TYPE

		ASSUME	EDI:NOTHING

INSTALL_LTYPE_GTYPE	ENDP


INSTALL_CSUE_GTYPE	PROC	NEAR
		;
		;ESI (EBX) IS LTYPE_STRUCTURE, RETURN EQUIVALENT GLOBAL TYPE IN EAX
		;EAX IS HASH
		;
		PUSH	EDI
		XOR	EDX,EDX

		MOV	ECX,CV_GTYPE_HASH_LOG

		HASHDIV	CV_GTYPE_HASH

		LEA	EDI,[ECX+EDX*4-CV_GTYPE_STRUCT._CV_GTYPE_NEXT_HASH]
		MOV	EDX,[ECX+EDX*4]
L2$:
		TEST	EDX,EDX
		JZ	L30$

		CONVERT	EDI,EDX,CV_GTYPE_GARRAY
		ASSUME	EDI:PTR CV_GTYPE_STRUCT

		MOV	EAX,[ESI]._CV_LTYPE_HASH
		MOV	ECX,[EDI]._CV_GTYPE_HASH

		CMP	EAX,ECX
		JNZ	L3$

		MOV	AL,BPTR [ESI]._CV_LTYPE_ILEAF
		MOV	CL,BPTR [EDI]._CV_GTYPE_ILEAF

		CMP	CL,AL
		JNZ	L3$

		MOV	AL,[ESI]._CV_LTYPE_FLAGS
		MOV	CL,[EDI]._CV_GTYPE_FLAGS

		XOR	AL,CL
		PUSH	EDI

		TEST	AL,MASK CV_LTYPE_FWDREF
		JNZ	L5$

		MOV	ECX,DPTR [ESI]._CV_LTYPE_LENGTH

		AND	ECX,0FFFFH
		MOV	EAX,ESI

		ADD	ECX,5
		LEA	EDI,[EDI]._CV_GTYPE_LENGTH

		SHR	ECX,2
		LEA	ESI,[ESI]._CV_LTYPE_LENGTH

		REPE	CMPSD

		POP	EDI
		MOV	ESI,EAX

		JZ	L4$

L3$:
		MOV	EDX,[EDI]._CV_GTYPE_NEXT_HASH
		JMP	L2$

L30$:
		;
		;INSTALL NEW COPY
		;
		;EDI IS PLACE TO STORE INDEX # OF NEW TYPE
		;
		;HOW MUCH SPACE DO I NEED TO ALLOCATE?
		;
		MOV	CL,[ESI]._CV_LTYPE_FLAGS
		MOV	EAX,DPTR [ESI]._CV_LTYPE_LENGTH

		AND	CL,MASK CV_LTYPE_FWDREF
		JZ	L31$

		ADD	EAX,4				;FWDREF LENGTH MAY AFFECT
L31$:
		ADD	EAX,CV_GTYPE_STRUCT._CV_GTYPE_ILEAF+12		;PLUS DERIVATION STUFF
		PUSH	EBX

		AND	EAX,0FFFFH
		CALL	CV_GTYPE_POOL_GET

		MOV	EBX,EAX
		INSTALL_POINTER_GINDEX	CV_GTYPE_GARRAY
		MOV	[EDI]._CV_GTYPE_NEXT_HASH,EAX

		MOV	EDI,EBX
		MOV	EDX,EAX

		XOR	EAX,EAX
		MOV	ECX,CV_GTYPE_STRUCT._CV_GTYPE_HASH/4

		REP	STOSD
		ASSUME	EDI:NOTHING

		MOV	EAX,DPTR [ESI]._CV_LTYPE_NAMEOFF
		MOV	ECX,DPTR [ESI]._CV_LTYPE_LENGTH

		SUB	AL,CV_LTYPE_STRUCT._CV_LTYPE_LENGTH-CV_GTYPE_STRUCT._CV_GTYPE_LENGTH
		ADD	ECX,9			;HASH + LENGTH + 3

		MOV	DPTR [EBX].CV_GTYPE_STRUCT._CV_GTYPE_NAMEOFF,EAX
		AND	ECX,0FFFFH

		POP	EBX
		MOV	EAX,ESI

		SHR	ECX,2
		LEA	ESI,[ESI]._CV_LTYPE_HASH

		REP	MOVSD

		MOV	[EDI],ECX			;DERIVATION SUTFF
		MOV	[EDI+4],ECX

		MOV	[EDI+8],ECX
		MOV	ESI,EAX

		MOV	AL,[EAX].CV_LTYPE_STRUCT._CV_LTYPE_FLAGS

		TEST	AL,MASK CV_LTYPE_FWDREF
		JNZ	L4$
		;
		;STORE DERIVATION LIST STUFF
		;
		CALL	STORE_DERIVATION_LIST
L4$:
		LEA	EAX,[EDX+1000H-1]
		POP	EDI

		RET			;RETURNS ESI IS ORIGINAL TYPE

		ASSUME	EDI:PTR CV_GTYPE_STRUCT
L5$:
		;
		;JUST ONE OF THESE GUYS IF FWDREF
		;
		XOR	ECX,ECX

		MOV	CL,[ESI]._CV_LTYPE_NAMEOFF
		PUSH	ESI

		ADD	ESI,ECX
		MOV	CL,[EDI]._CV_GTYPE_NAMEOFF

		ADD	EDI,ECX
		GET_OMF_NAME_LENGTH

		MOV	ECX,EAX

		push	ECX
		push	EDX
		push	EDI
		mov	EAX,ESP
		push	EAX
		call	_get_omf_name_length_routine
		add	ESP,4
		pop	EDI
		pop	EDX
		pop	ECX
;		CALL	GET_OMF_NAME_LENGTH_EDI

		CMP	ECX,EAX
		JNZ	L6$

		REPE	CMPSB
L6$:
		POPM	ESI,EDI

		JNZ	L3$

		MOV	AL,[ESI]._CV_LTYPE_FLAGS
		MOV	ECX,DPTR [ESI]._CV_LTYPE_LENGTH

		TEST	AL,MASK CV_LTYPE_FWDREF
		JNZ	L7$

		PUSH	ESI
		AND	ECX,0FFFFH

		MOV	EAX,DPTR [ESI]._CV_LTYPE_NAMEOFF
		ADD	ECX,5

		SHR	ECX,2
		SUB	AL,CV_LTYPE_STRUCT._CV_LTYPE_LENGTH-CV_GTYPE_STRUCT._CV_GTYPE_LENGTH

		LEA	ESI,[ESI]._CV_LTYPE_LENGTH
		MOV	DPTR [EDI]._CV_GTYPE_NAMEOFF,EAX

		LEA	EDI,[EDI]._CV_GTYPE_LENGTH
		ASSUME	EDI:NOTHING

		REP	MOVSD

		MOV	[EDI],ECX		;DERIVATION STUFF
		MOV	[EDI+4],ECX

		POP	ESI
		MOV	[EDI+8],ECX

		CALL	STORE_DERIVATION_LIST
L7$:
		POP	EDI
		LEA	EAX,[EDX+1000H-1]

		RET

		ASSUME	EDI:NOTHING

INSTALL_CSUE_GTYPE	ENDP


STORE_DERIVATION_LIST	PROC	NEAR
		;
		;ESI IS LTYPE, EDX IS GTYPE
		;STORE INFO LIKE XREF INFO FOR NOW
		;
		MOV	CL,BPTR [ESI]._CV_LTYPE_ILEAF
		MOV	EAX,DPTR [ESI]._CV_LTYPE_WORD1		;GTYPE OF FIELDLIST IN HIGH WORD

		CMP	CL,I_LF_UNION				;NOT FOR UNION OR ENUM
		JAE	L9$

		SHR	EAX,16					;NOT IF FIELDLIST UNDEFINED
		JZ	L9$

		MOV	XR_GTYPE_GINDEX,EDX
		SUB	EAX,1000H-1

		PUSHM	ESI,EDX

		CONVERT	ESI,EAX,CV_GTYPE_GARRAY
		ASSUME	ESI:PTR CV_GTYPE_STRUCT

		MOV	EDX,DPTR [ESI]._CV_GTYPE_LENGTH
		MOV	ECX,CV_GTYPE_STRUCT._CV_GTYPE_WORD1	;POINT TO FIRST SUBTYPE

		MOV	EAX,EDX
		AND	EDX,0FFFFH

		SHR	EAX,16
		SUB	EDX,2

		PUSH	EDI
		JBE	L8$

		CMP	AL,I_LF_FIELDLIST	;HAS TO BE...
		JNZ	L8$

		LEA	EDI,[EDX+ECX]		;END OF RECORD

		ASSUME	ESI:NOTHING
L1$:
		;
		;GO TILL A NON-BASE-CLASS
		;
		MOV	AL,BPTR [ESI+ECX]			;LOAD LEAF ID

		CMP	AL,0
		JZ	L3$

		CMP	AL,1
		JZ	L2$

		CMP	AL,2
		JNZ	L8$
L2$:
		MOV	AX,WPTR [ESI+ECX+2]
		CALL	STORE_BASE

		MOV	AH,BPTR [ESI+ECX+9]
		ADD	ECX,10

		OR	AH,AH
		JNS	L22$

		MOV	AL,BPTR [ESI+ECX-2]
		CALL	SKIP_LEAF_SICXAX
L22$:
		MOV	AH,[ESI+ECX]
		ADD	ECX,2

		OR	AH,AH
		JNS	L7$

		JMP	L35$


L3$:
		MOV	AX,2[ESI+ECX]
		CALL	STORE_BASE

		MOV	AH,6[ESI+ECX+1]
		ADD	ECX,8

		OR	AH,AH
		JNS	L7$
L35$:
		MOV	AL,[ESI+ECX-2]
		CALL	SKIP_LEAF_SICXAX
L7$:
		CMP	EDI,ECX
		JBE	L8$
		;
		;MAY NEED TO ADJUST FOR ALIGNMENT
		;
		MOV	AL,[ESI+ECX]

		CMP	AL,0F0H
		JBE	L1$

		AND	EAX,0FH

		ADD	ECX,EAX

		CMP	EDI,ECX

		JA	L1$
L8$:
		POPM	EDI,EDX,ESI
L9$:
		RET

STORE_DERIVATION_LIST	ENDP


FLUSH_DERIVATIVES	PROC

		XOR	EAX,EAX

		MOV	XR_GTYPE_GINDEX,EAX
;		CALL	STORE_BASE
;		RET

FLUSH_DERIVATIVES	ENDP


STORE_BASE	PROC	NEAR
		;
		;EAX IS SOMETHING...
		;PRESERVE ECX
		;
		PUSH	ESI
		MOV	ESI,DERIV_PTR

		SHL	EAX,16
		MOV	EDX,XR_GTYPE_GINDEX

		OR	EAX,EDX
		MOV	EDX,DERIV_PTR_LIMIT

		MOV	[ESI],EAX
		ADD	ESI,4

		MOV	DERIV_PTR,ESI
		CMP	ESI,EDX

		POP	ESI
		JAE	NEW_DERIV_BLK

		RET

STORE_BASE	ENDP


NEW_DERIV_BLK	PROC
		;
		;ALLOCATE ANOTHER 16K BLOCK FOR STORING XREF INFORMATION
		;
		;	DD	NEXT_ENTRY
		;	DW	LOGICAL_BLOCK
		;

NEW_DERIV_BLK_INIT	LABEL	PROC

		MOV	EDX,DERIV_PTR
		CALL	GET_NEW_LOG_BLK 	;GET LOGICAL BLOCK

		TEST	EDX,EDX
		JZ	L5$

		MOV	[EDX],EAX
L51$:
		MOV	DERIV_PTR,EAX
		ADD	EAX,PAGE_SIZE-4

		MOV	DERIV_PTR_LIMIT,EAX

		RET

L5$:
		MOV	FIRST_DERIV_BLK,EAX
		JMP	L51$

NEW_DERIV_BLK	ENDP


CIRC_HELP	PROC	NEAR
		;
		;ESI (EBX) IS CIRCULAR BASE
		;DH IS MASK, DL IS DEFINING FLAG
		;
		;WE TRY INSTALLING A CSUE.
		;	1.  WE MAY END UP COMPARING AND MATCHING THE WHOLE MESS
		;	2.  WE MAY END UP DOING MORE INSTALLS FROM NEW COMPLETIONS OF FWDREFS
		;
		PUSHM	EDI,ESI

		MOV	EAX,CIRCULAR_CSUE
		PUSH	EBX

		TEST	EAX,EAX
		JZ	L99$

		PUSH	EDX
		CONVERT	ESI,EAX,CV_LTYPE_GARRAY
		ASSUME	ESI:PTR CV_LTYPE_STRUCT

		MOV	ECX,EAX
		MOV	EDI,CV_GTYPE_HASH_LOG
		;
		;OK, TRY INSTALLING THIS THING...
		;
		MOV	EAX,[ESI]._CV_LTYPE_HASH
		XOR	EDX,EDX

		HASHDIV	CV_GTYPE_HASH

		MOV	EAX,[EDI+EDX*4]
		LEA	EDI,[EDI+EDX*4 - CV_GTYPE_STRUCT._CV_GTYPE_NEXT_HASH]
		ASSUME	EDI:PTR CV_GTYPE_STRUCT

		TEST	EAX,EAX
		JNZ	L11$

		JMP	L3$

L99$:
		MOV	ECX,EBX
		MOV	AX,CVP_CIRC_NO_CSUE_ERR

		CALL	ERR_HEX_ABORT

L12$:
		PUSHM	EBX,EDX
L1$:
		MOV	EAX,[EDI]._CV_GTYPE_NEXT_HASH

		TEST	EAX,EAX
		JZ	L3$
L11$:
		CONVERT	EDI,EAX,CV_GTYPE_GARRAY
		ASSUME	EDI:PTR CV_GTYPE_STRUCT

		MOV	EDX,EAX

		MOV	EAX,[ESI]._CV_LTYPE_HASH
		MOV	ECX,[EDI]._CV_GTYPE_HASH

		CMP	EAX,ECX
		JNZ	L1$

		MOV	AL,BPTR [ESI]._CV_LTYPE_ILEAF
		MOV	CL,BPTR [EDI]._CV_GTYPE_ILEAF

		CMP	AL,CL
		JNZ	L1$
		;
		;GO AHEAD AND COMPARE NAME
		;
		XOR	EAX,EAX
		XOR	ECX,ECX

		MOV	AL,[ESI]._CV_LTYPE_NAMEOFF
		MOV	CL,[EDI]._CV_GTYPE_NAMEOFF

		PUSH	ESI
		ADD	ESI,EAX

		PUSH	EDI
		ADD	EDI,ECX

		GET_OMF_NAME_LENGTH

		MOV	ECX,EAX

		push	ECX
		push	EDX
		push	EDI
		mov	EAX,ESP
		push	EAX
		call	_get_omf_name_length_routine
		add	ESP,4
		pop	EDI
		pop	EDX
		pop	ECX
;		CALL	GET_OMF_NAME_LENGTH_EDI

		CMP	ECX,EAX
		JNZ	L15$

		REPE	CMPSB

L15$:
		POPM	EDI,ESI

		JNZ	L1$
		;
		;NAME MATCHES
		;
		;IF GLOBAL GUY IS FORWARD, WE ARE DONE
		;
		MOV	AL,[EDI]._CV_GTYPE_FLAGS
		MOV	ECX,EDX

		TEST	AL,MASK CV_LTYPE_FWDREF
		JNZ	L2$			;GO COPY CONTENTS
		;
		;NEED TO SET UP DEEP COMPARE
		;
		POP	EDX
		CALL	DO_DEEP_COMPARE

		POP	EBX
		JNZ	L12$

		POPM	ESI,EDI

		RET

L2$:
		LEA	EAX,[EDX+1000H-1]
		POP	EDX

		MOV	[ESI]._CV_LTYPE_GTYPE,EAX

		OR	[ESI]._CV_LTYPE_FLAGS,MASK CV_LTYPE_INSTALLED
		JMP	L32$

L3$:
		;
		;INSTALL NEW COPY
		;
		;EDI IS PLACE TO STORE INDEX # OF NEW TYPE
		;
		;HOW MUCH SPACE DO I NEED TO ALLOCATE?
		;
		MOV	EAX,DPTR [ESI]._CV_LTYPE_LENGTH

		ADD	EAX,CV_GTYPE_STRUCT._CV_GTYPE_ILEAF+12		;PLUS DERIVATION STUFF		;CANNOT BE FWDREF

		AND	EAX,0FFFFH
		CALL	CV_GTYPE_POOL_GET

		MOV	EBX,EAX
		INSTALL_POINTER_GINDEX	CV_GTYPE_GARRAY

		MOV	[EDI]._CV_GTYPE_NEXT_HASH,EAX
		ADD	EAX,1000H-1
L31$:
		POP	EDX
		MOV	CL,[ESI]._CV_LTYPE_FLAGS

		MOV	[ESI]._CV_LTYPE_GTYPE,EAX
		OR	CL,MASK CV_LTYPE_INSTALLED

		XOR	EAX,EAX
		MOV	[ESI]._CV_LTYPE_FLAGS,CL
		;
		;DEFINE IT AS FWDREF FIRST...
		;
		MOV	EDI,EBX
		MOV	ECX,CV_GTYPE_STRUCT._CV_GTYPE_HASH/4

		REP	STOSD
		ASSUME	EDI:NOTHING

		MOV	EAX,DPTR [ESI]._CV_LTYPE_NAMEOFF	;AND FLAGS
		MOV	ECX,DPTR [ESI]._CV_LTYPE_LENGTH

		SUB	AL,CV_LTYPE_STRUCT._CV_LTYPE_LENGTH-CV_GTYPE_STRUCT._CV_GTYPE_LENGTH
		ADD	ECX,9					;HASH + LENGTH + 3

		OR	AH,MASK CV_LTYPE_FWDREF
		AND	ECX,0FFFFH

		SHR	ECX,2
		MOV	DPTR [EBX].CV_GTYPE_STRUCT._CV_GTYPE_NAMEOFF,EAX

		MOV	EAX,ESI
		LEA	ESI,[ESI]._CV_LTYPE_HASH

		REP	MOVSD

		MOV	[EDI],ECX
		MOV	[EDI+4],ECX

		MOV	ESI,EAX
		MOV	[EDI+8],ECX

		MOV	EDI,EBX
		ASSUME	EDI:PTR CV_GTYPE_STRUCT
L32$:
		CALL	SUB_DEFINE		;GO DEFINE EVERYTHING I TOUCH
		;
		;NOW UPDATE GTYPE
		;
		MOV	EAX,DPTR [ESI]._CV_LTYPE_NAMEOFF
		MOV	ECX,DPTR [ESI]._CV_LTYPE_LENGTH

		SUB	AL,CV_LTYPE_STRUCT._CV_LTYPE_LENGTH-CV_GTYPE_STRUCT._CV_GTYPE_LENGTH
		AND	ECX,0FFFFH

		MOV	DPTR [EDI]._CV_GTYPE_NAMEOFF,EAX
		ADD	ECX,9			;HASH + LENGTH + 3

		SHR	ECX,2
		LEA	EDI,[EDI]._CV_GTYPE_HASH
		ASSUME	EDI:NOTHING

		MOV	EAX,ESI
		LEA	ESI,[ESI]._CV_LTYPE_HASH

		REP	MOVSD

		MOV	[EDI],ECX
		MOV	ESI,EAX

		MOV	[EDI+4],ECX
		MOV	[EDI+8],ECX

		PUSH	EDX
		MOV	EDX,[ESI]._CV_LTYPE_GTYPE

		CALL	STORE_DERIVATION_LIST

		POPM	EDX,EBX

		POPM	ESI,EDI

		OR	EAX,EAX

		RET

CIRC_HELP	ENDP


DO_DEEP_COMPARE	PROC	NEAR
		;
		;ESI (EBX) IS LTYPE, EDI (ECX) IS GTYPE. IT IS A CSUE.  NAME MATCHES.  DO DEEP COMPARE
		;EDX IS REFERENCE MASK AND FLAGS
		;
		ASSUME	ESI:PTR CV_LTYPE_STRUCT,EDI:PTR CV_GTYPE_STRUCT

		PUSHM	EBX,ECX

		PUSH	EDX
		MOV	[ESI]._CV_LTYPE_GTYPE,ECX

		MOV	[ESI]._CV_LTYPE_COMP_BASE,ECX
		MOV	AL,[ESI]._CV_LTYPE_FLAGS

		MOV	EBX,ECX					;EBX IS GTYPE CSUE
		OR	AL,MASK CV_LTYPE_COMPARING

		MOV	ECX,[ESI]._CV_LTYPE_CIRC_CNT
		MOV	[ESI]._CV_LTYPE_FLAGS,AL
L1$:
		MOV	EAX,[ESI]._CV_LTYPE_CIRC_CNT
		PUSH	ECX

		CMP	EAX,CV_MINI_CIRCS
		MOV	EAX,[ESI]._CV_LTYPE_CIRC_PTR

		MOV	EDX,0
		JA	L3$

		MOV	EAX,[ESI+ECX*4]._CV_LTYPE_CIRC1-4
L31$:

		MOV	CL,BYTE PTR[ESI+EAX]
		MOV	DL,BPTR ([EDI+EAX]._CV_GTYPE_LENGTH - CV_LTYPE_STRUCT._CV_LTYPE_LENGTH)

		MOV	CH,BYTE PTR[ESI+EAX+1]
		MOV	DH,BPTR ([EDI+EAX]._CV_GTYPE_LENGTH - CV_LTYPE_STRUCT._CV_LTYPE_LENGTH + 1)

		MOV	EAX,EBX
		CALL	SUB_DEEP_COMPARE

		POP	ECX
		JNZ	L5$

		DEC	ECX
		JNZ	L1$
		;
		;MARK ALL THESE DEFINED...
		;
		POP	EDX

		PUSH	EDX
		CALL	DO_MARK_DEFINED

		CMP	EAX,EAX
L5$:
		POP	EDX

		POPM	ECX,EBX

		RET

L3$:
		MOV	EAX,[EAX+ECX*4]-4
		JMP	L31$

DO_DEEP_COMPARE	ENDP


DO_MARK_DEFINED	PROC	NEAR
		;
		;MUCH LIKE COMPARE, EXCEPT, JUST GO DOWN LTYPES SETTING DEFINED BIT...
		;ESI (EBX) IS CURRENT LTYPE
		;EDX IS REFERENCE MASK AND BIT
		;
		;RETURN IF ALREADY COMPARING FROM SAME BASE GINDEX
		;
		ASSUME	ESI:PTR CV_LTYPE_STRUCT

		MOV	AL,[ESI]._CV_LTYPE_FLAGS
		MOV	ECX,[ESI]._CV_LTYPE_GTYPE

		TEST	AL,MASK CV_LTYPE_INSTALLED
		JNZ	L9$

		OR	AL,MASK CV_LTYPE_INSTALLED
		ADD	ECX,1000H-1

		MOV	[ESI]._CV_LTYPE_FLAGS,AL
		MOV	[ESI]._CV_LTYPE_GTYPE,ECX
		;
		;IF CSUE, AND GTYPE IS FWDREF, ONLY COMPARE NAME...
		;
		TEST	AL,MASK CV_LTYPE_CSUE
		JZ	L2$

		SUB	ECX,1000H-1

		CONVERT	EAX,ECX,CV_GTYPE_GARRAY

		TEST	[EAX].CV_GTYPE_STRUCT._CV_GTYPE_FLAGS,MASK CV_LTYPE_FWDREF
		JNZ	L7$
L2$:
		PUSH	EBX
		XOR	EBX,EBX
L21$:
		;
		;GET NEXT OFFSET
		;
		MOV	EAX,[ESI]._CV_LTYPE_CIRC_CNT
		MOV	ECX,[ESI]._CV_LTYPE_CIRC_PTR

		CMP	EAX,CV_MINI_CIRCS
		JA	L27$

		MOV	ECX,[ESI+EBX*4]._CV_LTYPE_CIRC1
L28$:
		MOV	EAX,(- (1000H-1)) AND 0FFFFH
		PUSH	ESI

		ADD	AX,WPTR [ESI+ECX]

		CONVERT	ESI,EAX,CV_LTYPE_GARRAY

		CALL	DO_MARK_DEFINED

		POP	ESI
		INC	EBX

		CMP	[ESI]._CV_LTYPE_CIRC_CNT,EBX
		JA	L21$

		POP	EBX
L9$:
		RET

L27$:
		MOV	ECX,[ECX+EBX*4]
		JMP	L28$

L7$:
		;
		;GTYPE IS FWDREF CSUE
		;
		PUSHM	EDI,EAX

		CALL	SUB_DEFINE		;GO DEFINE EVERYTHING I TOUCH

		POP	EDI
		MOV	EAX,DPTR [ESI]._CV_LTYPE_NAMEOFF

		MOV	ECX,DPTR [ESI]._CV_LTYPE_LENGTH
		SUB	AL,CV_LTYPE_STRUCT._CV_LTYPE_LENGTH-CV_GTYPE_STRUCT._CV_GTYPE_LENGTH

		ADD	ECX,5
		MOV	DPTR [EDI]._CV_GTYPE_NAMEOFF,EAX

		AND	ECX,0FFFFH
		LEA	EDI,[EDI]._CV_GTYPE_LENGTH
		ASSUME	EDI:NOTHING

		SHR	ECX,2
		MOV	EAX,ESI

		LEA	ESI,[ESI]._CV_LTYPE_LENGTH

		REP	MOVSD

		MOV	ESI,EAX
		MOV	[EDI],ECX

		MOV	[EDI+4],ECX
		MOV	[EDI+8],ECX

		PUSH	EDX
		MOV	EDX,[ESI]._CV_LTYPE_GTYPE

		CALL	STORE_DERIVATION_LIST

		POPM	EDX,EDI

		RET

DO_MARK_DEFINED	ENDP


SUB_COMP_VARS	STRUC

SDCV_LTYPE_BP		DD	?
SDCV_GTYPE_BP		DD	?
SDCV_BASE_BP		DD	?
SDCV_CIRC_NUMBER_BP	DD	?
SDCV_OFFSET_BP		DD	?

SUB_COMP_VARS	ENDS


FIX	MACRO	X

X	EQU	([EBP-SIZE SUB_COMP_VARS].(X&_BP))

	ENDM


FIX	SDCV_LTYPE
FIX	SDCV_GTYPE
FIX	SDCV_BASE
FIX	SDCV_OFFSET
FIX	SDCV_CIRC_NUMBER


SUB_DEEP_COMPARE	PROC	NEAR
		;
		;ECX IS AN LTYPE, EDX IS A GTYPE, EAX IS GTYPE OF BASE CSUE
		;COMPARE TO SEE IF THEY MATCH
		;
		PUSH	ESI
		SUB	ECX,1000H-1

		SUB	EDX,1000H-1
		JBE	L02$

		CONVERT	ESI,ECX,CV_LTYPE_GARRAY
		ASSUME	ESI:PTR CV_LTYPE_STRUCT
		;
		;RETURN IF ALREADY COMPARING FROM SAME BASE GINDEX
		;
		MOV	CL,[ESI]._CV_LTYPE_FLAGS

		AND	CL,MASK CV_LTYPE_COMPARING
		JZ	L1$

		CMP	[ESI]._CV_LTYPE_COMP_BASE,EAX
		JNZ	L1$

		CMP	[ESI]._CV_LTYPE_GTYPE,EDX
		POP	ESI

		RET

L02$:
		POP	ESI
		OR	AL,-1

		RET

L1$:
		PUSHM	EDI,EBX,EBP

		MOV	EBP,ESP
		ASSUME	EBP:PTR SUB_COMP_VARS
		SUB	ESP,SIZE SUB_COMP_VARS

		MOV	[ESI]._CV_LTYPE_GTYPE,EDX
		MOV	CL,[ESI]._CV_LTYPE_FLAGS

		MOV	[ESI]._CV_LTYPE_COMP_BASE,EAX
		OR	CL,MASK CV_LTYPE_COMPARING

		MOV	SDCV_LTYPE,ESI
		MOV	[ESI]._CV_LTYPE_FLAGS,CL

		MOV	SDCV_BASE,EAX
		CONVERT	EDI,EDX,CV_GTYPE_GARRAY
		ASSUME	EDI:PTR CV_GTYPE_STRUCT
		;
		;IF CSUE, AND GTYPE IS FWDREF, ONLY COMPARE NAME...
		;
		MOV	SDCV_GTYPE,EDI
		MOV	BL,BPTR [ESI]._CV_LTYPE_ILEAF

		MOV	CL,BPTR [EDI]._CV_GTYPE_ILEAF
		MOV	AL,[EDI]._CV_GTYPE_FLAGS

		CMP	BL,CL
		JNZ	L89$

		TEST	AL,MASK CV_LTYPE_CSUE
		JZ	L2$

		TEST	AL,MASK CV_LTYPE_FWDREF
		JNZ	L7$
L2$:
		;
		;COMPARE VARIABLE AND NON-VARIABLE PARTS
		;
		MOV	EAX,CV_LTYPE_STRUCT._CV_LTYPE_LENGTH
		XOR	ECX,ECX

		;
		;GET NEXT OFFSET
		;
		MOV	SDCV_OFFSET,EAX
		MOV	EAX,[ESI]._CV_LTYPE_CIRC_CNT
L21$:
		MOV	SDCV_CIRC_NUMBER,ECX
		MOV	EDX,[ESI]._CV_LTYPE_CIRC_PTR

		CMP	EAX,CV_MINI_CIRCS
		JA	L27$

		MOV	ECX,[ESI+ECX*4]._CV_LTYPE_CIRC1
L28$:
		MOV	EAX,SDCV_OFFSET

		SUB	ECX,EAX			;# OF BYTES TO COMPARE
		ADD	ESI,EAX

		SHR	ECX,1
		LEA	EDI,[EDI+EAX+CV_GTYPE_STRUCT._CV_GTYPE_LENGTH - CV_LTYPE_STRUCT._CV_LTYPE_LENGTH]

		LEA	EAX,[EAX+ECX*2+2]

		REPE	CMPSW

		MOV	SDCV_OFFSET,EAX		;PLACE TO START NEXT COMPARE
		JNZ	L89$
		;
		;IF MORE INDEXES LEFT, NEST AND COMPARE THOSE...
		;
		XOR	EDX,EDX
		MOV	CL,BYTE PTR[ESI]

		MOV	DL,BYTE PTR[EDI]
		MOV	CH,BYTE PTR[ESI+1]

		MOV	DH,BYTE PTR[EDI+1]
		MOV	EAX,SDCV_BASE

		CALL	SUB_DEEP_COMPARE

		MOV	ESI,SDCV_LTYPE
		JNZ	L89$

		MOV	ECX,SDCV_CIRC_NUMBER
		MOV	EDI,SDCV_GTYPE

		INC	ECX
		MOV	EAX,[ESI]._CV_LTYPE_CIRC_CNT

		CMP	EAX,ECX
		JA	L21$
		;
		;SET UP TO COMPARE BYTES AT END
		;
		MOV	ECX,DPTR [ESI]._CV_LTYPE_LENGTH
		MOV	EAX,SDCV_OFFSET

		ADD	ECX,CV_LTYPE_STRUCT._CV_LTYPE_ILEAF+1
		ADD	ESI,EAX

		AND	ECX,0FFFEH
		ADD	EDI,EAX

		SUB	ECX,EAX			;# OF BYTES TO COMPARE
		JZ	L89$

		SHR	ECX,1
		LEA	EDI,[EDI + CV_GTYPE_STRUCT._CV_GTYPE_LENGTH - CV_LTYPE_STRUCT._CV_LTYPE_LENGTH]

		REPE	CMPSW

		JMP	L89$

L27$:
		MOV	ECX,[EDX+ECX*4]
		JMP	L28$

L7$:
		;
		;FWDREF CSUE
		;
		;JUST COMPARE NAME, IF IT MATCHES, ASSUME MATCH, FIX LATER
		;IN MARK_DEFINED
		;
		XOR	ECX,ECX
		XOR	EDX,EDX

		MOV	CL,[ESI]._CV_LTYPE_NAMEOFF
		MOV	DL,[EDI]._CV_GTYPE_NAMEOFF

		ADD	ESI,ECX
		ADD	EDI,EDX

		GET_OMF_NAME_LENGTH

		MOV	ECX,EAX

		push	ECX
		push	EDX
		push	EDI
		mov	EAX,ESP
		push	EAX
		call	_get_omf_name_length_routine
		add	ESP,4
		pop	EDI
		pop	EDX
		pop	ECX
;		CALL	GET_OMF_NAME_LENGTH_EDI

		CMP	ECX,EAX
		JNZ	L6$

		REPE	CMPSB
L6$:
L89$:
		MOV	ESP,EBP

		POPM	EBP,EBX,EDI,ESI

		RET

		ASSUME	EDI:NOTHING

SUB_DEEP_COMPARE	ENDP


SUB_DEFINE	PROC	NEAR
		;
		;ESI IS LTYPE, EDX IS CIRC FLAGS
		;
		PUSHM	EDI,EBX

		MOV	EBX,[ESI]._CV_LTYPE_CIRC_CNT		;START AT LAST GUY
L1$:
		MOV	EAX,[ESI]._CV_LTYPE_CIRC_CNT
		MOV	ECX,[ESI]._CV_LTYPE_CIRC_PTR

		CMP	EAX,CV_MINI_CIRCS
		JA	L3$

		MOV	EDI,[ESI+EBX*4]._CV_LTYPE_CIRC1-4
L31$:
		MOV	AX,WPTR [ESI+EDI]	;CIRCULAR REFERENCE I MADE
		CALL	CONVERT_CIRCULAR_REF

		MOV	ECX,[ESI]._CV_LTYPE_CIRC_CNT
		JC	L5$
		;
		;GREAT, WE DEFINED IT!
		;
		MOV	WPTR [ESI+EDI],AX
		DEC	ECX

		MOV	[ESI]._CV_LTYPE_CIRC_CNT,ECX
		JZ	L6$		;ALL DONE!
		;
		;MOVE LIST DOWN IF COUNTS DON'T MATCH
		;
		DEC	EBX

		CMP	ECX,EBX
		JNZ	L4$
L45$:
		;
		;DID WE JUST CHANGE TO SMALL SIZE?
		;
		CMP	ECX,CV_MINI_CIRCS
		JZ	L48$
L481$:
		TEST	EBX,EBX
		JNZ	L1$

		POPM	EBX,EDI

		RET

L48$:
		PUSH	ESI
		LEA	EDI,[ESI]._CV_LTYPE_CIRC1

		MOV	ESI,[ESI]._CV_LTYPE_CIRC_PTR
		MOV	ECX,CV_MINI_CIRCS

		REP	MOVSD

		POP	ESI
		JMP	L481$

L5$:
		DEC	EBX
		JNZ	L1$
L6$:
		POPM	EBX,EDI
		;
		;OK, THIS ONE IS COMPLETELY DEFINED!
		;
		RET

L3$:
		MOV	EDI,[ECX+EBX*4]-4
		JMP	L31$

L4$:
		;
		;MOVE LIST DOWN
		;
		PUSH	ESI
		CMP	ECX,CV_MINI_CIRCS

		LEA	EAX,[ESI]._CV_LTYPE_CIRC1
		JB	L42$

		MOV	EAX,[ESI]._CV_LTYPE_CIRC_PTR
L42$:
		PUSH	ECX
		SUB	ECX,EBX			;# OF WORDS TO MOVE

		LEA	EDI,[EAX+EBX*4]
		LEA	ESI,[EAX+EBX*4+4]

		REP	MOVSD

		POPM	ECX,ESI

		JMP	L45$

SUB_DEFINE	ENDP


CONVERT_CIRCULAR_REF	PROC	NEAR
		;
		;AX IS LTYPE, RETURN A GTYPE IF POSSIBLE
		;DX IS REFERENCE MASK AND FLAGS
		;
		PUSH	ESI
		LEA	ECX,[EAX- (1000H-1)]

		CONVERT	ESI,ECX,CV_LTYPE_GARRAY
		ASSUME	ESI:PTR CV_LTYPE_STRUCT

		MOV	AL,[ESI]._CV_LTYPE_FLAGS

		TEST	AL,MASK CV_LTYPE_INSTALLED
		JZ	L2$

		MOV	EAX,[ESI]._CV_LTYPE_GTYPE
		POP	ESI

		RET

L15$:
		;
		;WE HAVE A CIRCULAR SITUATION
		;
		;UPDATE CIRCULAR_BASE AND CIRCULAR_INDEX IF NECESSARY
		;
		TEST	AL,MASK CV_LTYPE_CSUE
		JZ	L16$

		MOV	CIRCULAR_CSUE,ECX
L16$:
		MOV	EAX,[ESI]._CV_LTYPE_GTYPE

		TEST	EAX,EAX
		JZ	L165$

		CONVERT	ESI,EAX,CV_LTYPE_GARRAY

		MOV	ECX,EAX
		JMP	L16$

L165$:
		MOV	EAX,[ESI]._CV_LTYPE_NEST_LEVEL	;NEST LEVEL FOR THIS TYPE

		CMP	CIRCULAR_BASE,EAX
		JBE	L17$

		MOV	CIRCULAR_BASE,EAX
		MOV	CIRCULAR_INDEX,ECX
L17$:
		CMP	ECX,-1			;FLAG CIRCULAR REFERENCE
		POP	ESI

		RET

L2$:
		;
		;IF IT IS ALREADY BEING DEFINED, WE'VE GOT A CIRCULAR PROBLEM...
		;
		TEST	AL,DL			;MASK CV_LTYPE_DEFINING
		JNZ	L15$

		PUSH	EBX
		MOV	EBX,ECX
		;
		;OK, CONVERT ANY TYPES I REFERENCE
		;
		AND	AL,DH			;CLEAR OLD DEFINING_BIT
		MOV	ECX,CIRCULAR_BASE

		OR	AL,DL			;MASK CV_LTYPE_DEFINING
		PUSH	ECX

		MOV	[ESI]._CV_LTYPE_FLAGS,AL
		MOV	EAX,CIRCULAR_INDEX
		;
		;SET UP BASIS FOR A NON-CIRCULAR SEARCH
		;
		PUSH	EAX
		MOV	ECX,CIRCULAR_CSUE

		XOR	EAX,EAX
		PUSH	ECX

		MOV	[ESI]._CV_LTYPE_GTYPE,EAX
		MOV	CIRCULAR_INDEX,EAX

		MOV	ECX,CONVERT_NEST_LEVEL
		MOV	CIRCULAR_CSUE,EAX

		DEC	EAX
		INC	ECX

		MOV	CIRCULAR_BASE,EAX
		MOV	CONVERT_NEST_LEVEL,ECX

		MOV	[ESI]._CV_LTYPE_NEST_LEVEL,ECX
		CALL	SUB_DEFINE		;CONVERT ANY TYPES I TOUCH	ESI,EDX

		MOV	EAX,CIRCULAR_BASE
		MOV	ECX,CONVERT_NEST_LEVEL

		OR	EAX,EAX
		JNS	L7$			;NO-SIGN MEANS WE HAVE A CIRCULAR PROBLEM
		;
		;HOPEFULLY MOST ARE THIS KIND...
		;
		DEC	ECX
		POP	EAX

		MOV	CONVERT_NEST_LEVEL,ECX
		MOV	CIRCULAR_CSUE,EAX

		POP	ECX
		MOV	AL,[ESI]._CV_LTYPE_FLAGS

		MOV	CIRCULAR_INDEX,ECX
		POP	ECX

		OR	AL,MASK CV_LTYPE_INSTALLED
		MOV	CIRCULAR_BASE,ECX

		MOV	[ESI]._CV_LTYPE_FLAGS,AL
		PUSH	EDX

		TEST	AL,MASK CV_LTYPE_CSUE
		JNZ	L3$

		MOV	EAX,DPTR [ESI]._CV_LTYPE_LENGTH	;EXCLUDING LENGTH FIELD ITSELF
		LEA	ECX,[ESI]._CV_LTYPE_LENGTH

		AND	EAX,0FFFFH

		ADD	EAX,2				;COUNT LENGTH FIELD
		CALL	OPTI_HASH32_CASE		;RETURNS HASH IN EAX

		MOV	[ESI]._CV_LTYPE_HASH,EAX
		CALL	INSTALL_LTYPE_GTYPE	;DO NORMAL INSTALL

		POP	EDX
		MOV	[ESI]._CV_LTYPE_GTYPE,EAX

		POPM	EBX,ESI

		OR	EAX,EAX

		RET

L3$:
		MOV	EAX,[ESI]._CV_LTYPE_HASH
		CALL	INSTALL_CSUE_GTYPE

		POP	EDX
		MOV	[ESI]._CV_LTYPE_GTYPE,EAX

		POPM	EBX,ESI

		OR	EAX,EAX

		RET

L7$:
		;
		;CIRCULAR IN PROGRESS...
		;
		CMP	ECX,EAX		;ECX IS CONVERT_NEST_LEVEL
		JNZ	L71$		;EAX IS CIRCULAR BASE

		CMP	CIRCULAR_INDEX,EBX
		JZ	L8$
L71$:
		;
		;NO, NOT REALLY DONE WITH THIS CIRCULAR MESS.
		;
		POP	EAX
		;
		;DEFINE A CSUE IF POSSIBLE
		;
		TEST	EAX,EAX
		JNZ	L72$

		MOV	AL,[ESI]._CV_LTYPE_FLAGS

		TEST	AL,MASK CV_LTYPE_CSUE
		JZ	L73$

		MOV	CIRCULAR_CSUE,EBX
		JMP	L73$

L72$:
		MOV	CIRCULAR_CSUE,EAX
L73$:
		POP	EBX
		DEC	ECX

		POP	EAX
		MOV	CONVERT_NEST_LEVEL,ECX

		CMP	CIRCULAR_BASE,EAX	;KEEP NEW BASE & INDEX IF BASE IS < OLD BASE
		JB	L74$

		MOV	CIRCULAR_BASE,EAX
		MOV	CIRCULAR_INDEX,EBX

		SUB	ECX,-1
L74$:
		MOV	EAX,CIRCULAR_BASE
		MOV	ECX,CIRCULAR_INDEX

		POP	EBX
		MOV	[ESI]._CV_LTYPE_GTYPE,ECX

		MOV	[ESI]._CV_LTYPE_NEST_LEVEL,EAX
		POP	ESI

		RET			;CARRY SET

L8$:
		;
		;OK, I AM CIRCULAR BASE...
		;
		PUSH	EDX
		XOR	EDX,-1

		MOV	AL,DL
		MOV	DL,DH

		MOV	DH,AL
		CALL	CIRC_HELP

		POP	EDX
		MOV	ECX,CONVERT_NEST_LEVEL

		POP	EAX
		DEC	ECX

		POP	EBX
		MOV	CONVERT_NEST_LEVEL,ECX

		MOV	CIRCULAR_CSUE,EAX
		POP	EAX

		MOV	CIRCULAR_INDEX,EBX
		MOV	CIRCULAR_BASE,EAX

		MOV	EAX,[ESI]._CV_LTYPE_GTYPE
		POP	EBX

		POP	ESI
		OR	EAX,EAX

		RET

CONVERT_CIRCULAR_REF	ENDP


LTYPE_NO_TYPES	PROC	NEAR

		RET

LTYPE_NO_TYPES	ENDP


LTYPE_POINTER	PROC	NEAR
		;
		;
		;
		CALL	LTYPE_TYPE_4			;THAT MUCH FOR SURE

		MOV	AL,BPTR [ESI]._CV_LTYPE_WORD1	;FIRST WORD AFTER LEAF IS ATTRIBUTE FLAGS

		TEST	AL,0E0H
		JS	LTYPE_TYPE_V6

		JNZ	L1$				;REF, NOTHING MORE
		;
		;POINTER, CHECK FURTHER
		;
		AND	AL,1FH

		CMP	AL,8
		JZ	LTYPE_TYPE_V6

		JA	L1$

		CMP	AL,3
		JA	L2$
L1$:
		RET

L2$:
		;
		;THESE HAVE A COMPLETE SYMBOL RECORD..., ASSUME JUST S_REGISTER, BPRELS, L&GDATAS
		;
		MOV	EAX,DPTR [ESI]._CV_LTYPE_WORD3.CV_SYMBOL_STRUCT._LENGTH
		MOV	ECX,CV_LTYPE_STRUCT._CV_LTYPE_WORD3+ CV_REG_STRUCT._TYPE

		SHR	EAX,16

		CMP	EAX,S_REGISTER
		JZ	LTYPE_TYPE_SICX

		ADD	ECX,2

		CMP	EAX,S_BPREL16
		JZ	LTYPE_TYPE_SICX

		ADD	ECX,2

		CMP	EAX,S_BPREL32
		JBE	LTYPE_TYPE_SICX

		ADD	ECX,2
;		JMP	LTYPE_TYPE_SICX

LTYPE_POINTER	ENDP


LTYPE_TYPE_SICX	PROC	NEAR
		;
		;
		;
		MOV	AH,BYTE PTR[ESI+ECX+1]

		CMP	AH,10H
		JAE	L1$

		RET

L1$:
		MOV	AL,BYTE PTR[ESI+ECX]
		PUSH	ECX

		AND	EAX,0FFFFH
		CALL	CONVERT_CV_LTYPE_GTYPE_A

		POP	ECX
		JC	L5$

		MOV	WPTR [ESI+ECX],AX

		RET

L5$:
		MOV	EDX,[ESI]._CV_LTYPE_CIRC_CNT

		MOV	[ESI+EDX*4]._CV_LTYPE_CIRC1,ECX
		INC	EDX

		MOV	[ESI]._CV_LTYPE_CIRC_CNT,EDX

		RET

LTYPE_TYPE_SICX	ENDP


LTYPE_DIMVARU	PROC	NEAR
		;
		;
		;
		MOV	EAX,DPTR [ESI]._CV_LTYPE_WORD1
		MOV	ECX,CV_LTYPE_STRUCT._CV_LTYPE_WORD2-2

		INC	EAX
		JMP	LTYPE_LIST1

LTYPE_DIMVARU	ENDP


LTYPE_OEM	PROC	NEAR
		;
		;
		;
		MOV	EAX,DPTR [ESI]._CV_LTYPE_WORD3
		MOV	ECX,CV_LTYPE_STRUCT._CV_LTYPE_WORD4-2

		JMP	LTYPE_LIST1

LTYPE_OEM	ENDP


LTYPE_ARGLIST	PROC	NEAR
		;
		;COUNT FOLLOWED BY TYPES
		;
		MOV	EAX,DPTR [ESI]._CV_LTYPE_WORD1
		MOV	ECX,CV_LTYPE_STRUCT._CV_LTYPE_WORD2-2
LTYPE_LIST1::
		AND	EAX,0FFFFH
		JZ	L9$

		PUSH	EBX
		MOV	EBX,EAX
L1$:
		ADD	ECX,2
		CALL	LTYPE_TYPE_SICX_BIG		;MIGHT BE LOTSA CIRCULAR REFS...

		DEC	EBX
		JNZ	L1$

		POP	EBX
L9$:
		RET

LTYPE_ARGLIST	ENDP


LTYPE_FIELDLIST	PROC	NEAR
		;
		;THIS CONTAINS A BUNCH OF SILLY TYPE 4XX TYPES
		;
		PUSH	EDI
		MOV	EDI,DPTR [ESI]._CV_LTYPE_LENGTH		;LENGTH OF FIELDLIST RECORD

		MOV	ECX,CV_LTYPE_STRUCT._CV_LTYPE_WORD1	;POINT TO FIRST SUBTYPE
		AND	EDI,0FFFFH

		SUB	EDI,2
		JBE	L9$

		PUSH	EBX
		XOR	EBX,EBX

		ADD	EDI,ECX
L1$:
		MOV	BL,BYTE PTR[ESI+ECX]			;LOAD LEAF ID
L2$:
		MOV	BH,BYTE PTR[ESI+ECX+1]
		ADD	ECX,2

		SUB	BH,4

		CMP	EBX,0DH
		JA	L99$				;UNKNOWN TYPE

		CALL	SUBTYPE_TBL[EBX*4]		;DO IT, UPDATE OFFSET TOO

		CMP	EDI,ECX
		JBE	L8$
		;
		;MAY NEED TO ADJUST FOR ALIGNMENT
		;
		MOV	BL,BYTE PTR[ESI+ECX]

		CMP	BL,0F0H
		JBE	L2$

		LEA	ECX,[ECX+EBX-0F0H]

		CMP	EDI,ECX
		JA	L1$
L8$:
		POP	EBX
L9$:
		POP	EDI

		RET

L99$:
		POPM	EBX,EDI

		MOV	AL,0
		push	EAX
		call	_err_abort

LTYPE_FIELDLIST	ENDP


LTYPE_MLIST	PROC	NEAR
		;
		;THIS CONTAINS A BUNCH OF SILLY TYPE 4XX TYPES
		;
		PUSH	EBX
		MOV	EBX,DPTR [ESI]._CV_LTYPE_LENGTH		;LENGTH OF FIELDLIST RECORD

		MOV	ECX,CV_LTYPE_STRUCT._CV_LTYPE_WORD2	;POINT TO FIRST SUBTYPE
		AND	EBX,0FFFFH

		SUB	EBX,2
		JBE	L9$

		ADD	EBX,ECX
L1$:
		CALL	LTYPE_TYPE_SICX_BIG
		ASSUME	ESI:NOTHING

		MOV	AL,[ESI+ECX-2]			;ATTRIBUTES
		ADD	ECX,4				;SKIP TYPE

		AND	AL,1CH

		CMP	AL,4*4
		JZ	L15$

		CMP	AL,6*4
		JNZ	L2$
L15$:
		ADD	ECX,4				;SKIP VTAB OFFSET
L2$:
		CMP	EBX,ECX
		JA	L1$
L9$:
		POP	EBX

		RET

LTYPE_MLIST	ENDP


SUB_BCLASS	PROC	NEAR
		;
		;
		;
		CALL	LTYPE_TYPE_SICX_BIG		;GLOBALIZE THIS TYPE

		MOV	AH,5[ESI+ECX]
		ADD	ECX,6

		OR	AH,AH
		JS	L5$

		RET

L5$:
		MOV	AL,[ESI+ECX-2]
		JMP	SKIP_LEAF_SICXAX

SUB_BCLASS	ENDP


SUB_VBCLASS	PROC	NEAR
		;
		;
		;
		CALL	LTYPE_TYPE_SICX_BIG		;VIRTUAL BASE CLASS

		ADD	ECX,2
		CALL	LTYPE_TYPE_SICX_BIG		;VIRTUAL BASE POINTER

		MOV	AH,5[ESI+ECX]
		ADD	ECX,6

		OR	AH,AH
		JS	L5$
L2$:
		MOV	AH,[ESI+ECX+1]
		ADD	ECX,2

		OR	AH,AH
		JS	L6$

		RET

L5$:
		MOV	AL,[ESI+ECX-2]
		CALL	SKIP_LEAF_SICXAX
		JMP	L2$

L6$:
		MOV	AL,[ESI+ECX-2]
		JMP	SKIP_LEAF_SICXAX

SUB_VBCLASS	ENDP


SUB_ENUMERATE	PROC	NEAR
		;
		;
		;
		MOV	AH,3[ESI+ECX]
		ADD	ECX,4

		OR	AH,AH
		JS	L5$
L1$:
		MOV	AL,[ESI+ECX]
		INC	ECX

		AND	EAX,0FFH
SUB_NAME_CONT::
		CMP	AL,-1
		JZ	L3$
L2$:
		ADD	ECX,EAX
		RET

L3$:
		MOV	DL,[ESI+ECX]

		TEST	DL,DL
		JNZ	L2$

		MOV	AX,[ESI+ECX+1]
		ADD	ECX,3

		ADD	ECX,EAX

		RET

L5$:
		MOV	AL,[ESI+ECX-2]
		CALL	SKIP_LEAF_SICXAX

		JMP	L1$

SUB_ENUMERATE	ENDP


SUB_METHOD	PROC	NEAR
		;
		;
		;
		ADD	ECX,2
;		JMP	SUB_FRIENDFCN

SUB_METHOD	ENDP


SUB_FRIENDFCN	PROC	NEAR
		;
		;
		;
		CALL	LTYPE_TYPE_SICX_BIG

		MOV	AL,2[ESI+ECX]
		ADD	ECX,3

		AND	EAX,0FFH
		JMP	SUB_NAME_CONT

SUB_FRIENDFCN	ENDP


SUB_MEMBER	PROC	NEAR
		;
		;
		;
		CALL	LTYPE_TYPE_SICX_BIG

		ADD	ECX,2
		JMP	SUB_ENUMERATE

SUB_MEMBER	ENDP


SUB_STMEMBER	PROC	NEAR
		;
		;
		;
		CALL	LTYPE_TYPE_SICX_BIG

		MOV	AL,4[ESI+ECX]
		ADD	ECX,5

		AND	EAX,0FFH
		JMP	SUB_NAME_CONT

SUB_STMEMBER	ENDP


SUB_VFUNCTAB	PROC	NEAR
		;
		;
		;
		CALL	LTYPE_TYPE_SICX_BIG

		ADD	ECX,2

		RET

SUB_VFUNCTAB	ENDP


SUB_ONEMETHOD	PROC	NEAR
		;
		;
		;
		ADD	ECX,2
		CALL	LTYPE_TYPE_SICX_BIG

		MOV	AL,6[ESI+ECX]
		ADD	ECX,7

		AND	EAX,0FFH
		JMP	SUB_NAME_CONT

SUB_ONEMETHOD	ENDP


SUB_VFUNCOFF	PROC	NEAR
		;
		;
		;
		CALL	LTYPE_TYPE_SICX_BIG

		ADD	ECX,6

		RET

SUB_VFUNCOFF	ENDP


LTYPE_TYPE_SICX_BIG	PROC	NEAR
		;
		;
		;
		MOV	AH,[ESI+ECX+1]
		PUSH	EDI

		CMP	AH,10H
		JB	L9$

		MOV	AL,[ESI+ECX]
		MOV	EDI,ECX

		AND	EAX,0FFFFH
		CALL	CONVERT_CV_LTYPE_GTYPE_A

		MOV	ECX,EDI
		JC	L5$

		MOV	WPTR [ESI+EDI],AX
L9$:
		POP	EDI

		RET

		ASSUME	ESI:PTR CV_LTYPE_STRUCT
L5$:
L51$:
		MOV	EDX,[ESI]._CV_LTYPE_CIRC_CNT

		CMP	EDX,CV_MINI_CIRCS
		JAE	L6$

		MOV	[ESI+EDX*4]._CV_LTYPE_CIRC1,ECX
		INC	EDX

		POP	EDI
		MOV	[ESI]._CV_LTYPE_CIRC_CNT,EDX

		RET

L6$:
		;
		;SPECIAL HANDLING OF >4 CIRCULAR REFERENCES
		;
		MOV	EDI,[ESI]._CV_LTYPE_MAX_CNT
		JZ	L8$

		CMP	EDI,EDX
		MOV	EDI,[ESI]._CV_LTYPE_CIRC_PTR

		JBE	L7$

		MOV	[EDI+EDX*4],ECX
		INC	EDX

		POP	EDI
		MOV	[ESI]._CV_LTYPE_CIRC_CNT,EDX

		RET

L7$:
		;
		;EDX == CURRENT MAX CNT, EDI IS OLD CIRC_PTR
		;
		PUSH	ECX
		MOV	ECX,EDX			;DWORDS TO MOVE

		LEA	EAX,[EDX*8]
		ADD	EDX,EDX			;DOUBLE IT IN SIZE

		MOV	[ESI]._CV_LTYPE_MAX_CNT,EDX	;TOTAL IN NEW SPACE
		CALL	CV_LTYPE_POOL_GET

		PUSH	ESI
		MOV	[ESI]._CV_LTYPE_CIRC_PTR,EAX

		MOV	ESI,EDI
		MOV	EDI,EAX

		REP	MOVSD

		POPM	ESI,ECX

		JMP	L51$

L8$:
		;
		;FIRST REF >CV_MINI_CIRCS
		;
		PUSH	ECX
		MOV	ECX,EDX			;DWORDS TO MOVE

		LEA	EAX,[EDX*8]		;BYTES TO ALLOCATE
		CALL	CV_LTYPE_POOL_GET

		MOV	EDI,EAX
		PUSH	ESI

		LEA	ESI,[ESI]._CV_LTYPE_CIRC1

		REP	MOVSD

		POPM	ESI,ECX

		MOV	EDX,CV_MINI_CIRCS*2
		MOV	[EDI],ECX

		MOV	[ESI]._CV_LTYPE_CIRC_PTR,EAX
		MOV	EAX,CV_MINI_CIRCS+1

		MOV	[ESI]._CV_LTYPE_MAX_CNT,EDX	;TOTAL IN NEW SPACE
		MOV	[ESI]._CV_LTYPE_CIRC_CNT,EAX

		POP	EDI

		RET

LTYPE_TYPE_SICX_BIG	ENDP


LTYPE_TYPE_2	PROC	NEAR
		;
		;TYPE AT OFFSET 2 FROM TYPE
		;
		MOV	EAX,DPTR [ESI]._CV_LTYPE_WORD1

		CMP	AH,10H
		JB	L9$

		AND	EAX,0FFFFH
		CALL	CONVERT_CV_LTYPE_GTYPE_A

		JC	L5$

		MOV	[ESI]._CV_LTYPE_WORD1,AX
L9$:
		RET

L5$:
		;
		;OOPS, I TOUCH A CIRCULAR TYPE
		;
		MOV	EAX,CV_LTYPE_STRUCT._CV_LTYPE_WORD1
		MOV	EDX,1

		MOV	[ESI]._CV_LTYPE_CIRC1,EAX
		MOV	[ESI]._CV_LTYPE_CIRC_CNT,EDX

		RET

LTYPE_TYPE_2	ENDP


LTYPE_TYPE_4	PROC	NEAR
		;
		;TYPE AT OFFSET 4 FROM TYPE
		;
		MOV	EAX,DPTR [ESI]._CV_LTYPE_WORD1

		CMP	EAX,10000000H
		JB	L9$

		SHR	EAX,16
		CALL	CONVERT_CV_LTYPE_GTYPE_A

		JC	L5$

		MOV	[ESI]._CV_LTYPE_WORD2,AX
L9$:
		RET

L5$:
		;
		;OOPS, I TOUCH A CIRCULAR TYPE
		;
		MOV	EAX,CV_LTYPE_STRUCT._CV_LTYPE_WORD2
		MOV	EDX,1

		MOV	[ESI]._CV_LTYPE_CIRC1,EAX
		MOV	[ESI]._CV_LTYPE_CIRC_CNT,EDX

		RET

LTYPE_TYPE_4	ENDP


LTYPE_TYPE_2_4	PROC	NEAR
		;
		;TYPES AT OFFSET 2 AND 4 FROM TYPE
		;
		MOV	EAX,DPTR [ESI]._CV_LTYPE_WORD1

		CMP	AH,10H
		JB	L1$

		AND	EAX,0FFFFH
		CALL	CONVERT_CV_LTYPE_GTYPE_A

		MOV	EDX,DPTR [ESI]._CV_LTYPE_WORD1
		JC	L4$

		MOV	[ESI]._CV_LTYPE_WORD1,AX
		MOV	EAX,EDX
L1$:
		CMP	EAX,10000000H
		JB	L9$

		SHR	EAX,16
		CALL	CONVERT_CV_LTYPE_GTYPE_A

		MOV	EDX,[ESI]._CV_LTYPE_CIRC_CNT
		JC	L5$

		MOV	[ESI]._CV_LTYPE_WORD2,AX
L9$:
		RET

L4$:
		MOV	EAX,CV_LTYPE_STRUCT._CV_LTYPE_WORD1
		MOV	ECX,1

		MOV	[ESI]._CV_LTYPE_CIRC1,EAX
		MOV	[ESI]._CV_LTYPE_CIRC_CNT,ECX

		MOV	EAX,EDX
		JMP	L1$

L5$:
		MOV	EAX,CV_LTYPE_STRUCT._CV_LTYPE_WORD2

		MOV	[ESI+EDX*4]._CV_LTYPE_CIRC1,EAX
		INC	EDX

		MOV	[ESI]._CV_LTYPE_CIRC_CNT,EDX

		RET

LTYPE_TYPE_2_4	ENDP


LTYPE_TYPE_2_4_6_12	PROC	NEAR
		;
		;TYPES AT OFFSET 2, 4, 6, AND 12 FROM TYPE
		;
		MOV	EAX,DPTR [ESI]._CV_LTYPE_WORD1

		CMP	AH,10H
		JB	L1$

		AND	EAX,0FFFFH
		CALL	CONVERT_CV_LTYPE_GTYPE_A		;3

		MOV	EDX,DPTR [ESI]._CV_LTYPE_WORD1
		JC	L4$

		MOV	[ESI]._CV_LTYPE_WORD1,AX
		MOV	EAX,EDX
L1$:
		CMP	EAX,10000000H
		JB	L3$

		SHR	EAX,16
		CALL	CONVERT_CV_LTYPE_GTYPE_A		;5

		MOV	EDX,[ESI]._CV_LTYPE_CIRC_CNT
		JC	L5$

		MOV	[ESI]._CV_LTYPE_WORD2,AX
L3$:
		CALL	LTYPE_TYPE_V6
		JMP	LTYPE_TYPE_V12

L4$:
		MOV	EAX,CV_LTYPE_STRUCT._CV_LTYPE_WORD1
		MOV	ECX,1

		MOV	[ESI]._CV_LTYPE_CIRC1,EAX
		MOV	[ESI]._CV_LTYPE_CIRC_CNT,ECX

		MOV	EAX,EDX
		JMP	L1$

L5$:
		MOV	EAX,CV_LTYPE_STRUCT._CV_LTYPE_WORD2

		MOV	[ESI+EDX*4]._CV_LTYPE_CIRC1,EAX
		INC	EDX

		MOV	[ESI]._CV_LTYPE_CIRC_CNT,EDX
		JMP	L3$

LTYPE_TYPE_2_4_6_12	ENDP


LTYPE_TYPE_4_10	PROC	NEAR
		;
		;TYPES AT OFFSET 4 AND 10 FROM TYPE
		;
		MOV	EAX,DPTR [ESI]._CV_LTYPE_WORD1

		CMP	EAX,10000000H
		JB	L1$

		SHR	EAX,16
		CALL	CONVERT_CV_LTYPE_GTYPE_A

		JC	L4$

		MOV	[ESI]._CV_LTYPE_WORD2,AX
L1$:
		MOV	EAX,DPTR [ESI]._CV_LTYPE_WORD5
L2$:
		CMP	AH,10H
		JB	L9$

		AND	EAX,0FFFFH
		CALL	CONVERT_CV_LTYPE_GTYPE_A

		MOV	EDX,[ESI]._CV_LTYPE_CIRC_CNT
		JC	L5$

		MOV	[ESI]._CV_LTYPE_WORD5,AX
L9$:
		RET

L4$:
		MOV	EAX,CV_LTYPE_STRUCT._CV_LTYPE_WORD2
		MOV	ECX,1

		MOV	[ESI]._CV_LTYPE_CIRC1,EAX
		MOV	[ESI]._CV_LTYPE_CIRC_CNT,ECX

		MOV	EAX,DPTR [ESI]._CV_LTYPE_WORD5
		JMP	L2$

L5$:
		MOV	EAX,CV_LTYPE_STRUCT._CV_LTYPE_WORD5

		MOV	[ESI+EDX*4]._CV_LTYPE_CIRC1,EAX
		INC	EDX

		MOV	[ESI]._CV_LTYPE_CIRC_CNT,EDX

		RET

LTYPE_TYPE_4_10	ENDP


LTYPE_TYPE_4_6	PROC	NEAR
		;
		;TYPES AT OFFSET 4 AND 6 FROM TYPE
		;
		MOV	EAX,DPTR [ESI]._CV_LTYPE_WORD1

		CMP	EAX,10000000H
		JB	L1$

		SHR	EAX,16
		CALL	CONVERT_CV_LTYPE_GTYPE_A

		JC	L4$
		MOV	[ESI]._CV_LTYPE_WORD2,AX
L1$:
LTYPE_TYPE_V6::
		MOV	EAX,DPTR [ESI]._CV_LTYPE_WORD3
L2$:
		CMP	AH,10H
		JB	L9$

		AND	EAX,0FFFFH
		CALL	CONVERT_CV_LTYPE_GTYPE_A

		MOV	EDX,[ESI]._CV_LTYPE_CIRC_CNT
		JC	L5$

		MOV	[ESI]._CV_LTYPE_WORD3,AX
L9$:
		RET

L4$:
		MOV	EAX,CV_LTYPE_STRUCT._CV_LTYPE_WORD2
		MOV	ECX,1

		MOV	[ESI]._CV_LTYPE_CIRC1,EAX
		MOV	[ESI]._CV_LTYPE_CIRC_CNT,ECX

		MOV	EAX,DPTR [ESI]._CV_LTYPE_WORD3
		JMP	L2$

L5$:
		MOV	EAX,CV_LTYPE_STRUCT._CV_LTYPE_WORD3

		MOV	[ESI+EDX*4]._CV_LTYPE_CIRC1,EAX
		INC	EDX

		MOV	[ESI]._CV_LTYPE_CIRC_CNT,EDX

		RET

LTYPE_TYPE_4_6	ENDP


LTYPE_TYPE_2_8	PROC	NEAR
		;
		;TYPES AT OFFSET 2 AND 8 FROM TYPE
		;
		MOV	EAX,DPTR [ESI]._CV_LTYPE_WORD1

		CMP	AH,10H
		JB	L1$

		AND	EAX,0FFFFH
		CALL	CONVERT_CV_LTYPE_GTYPE_A

		JC	L4$

		MOV	[ESI]._CV_LTYPE_WORD1,AX
L1$:
		MOV	EAX,DPTR [ESI]._CV_LTYPE_WORD3
L2$:
		CMP	EAX,10000000H
		JB	L9$

		SHR	EAX,16
		CALL	CONVERT_CV_LTYPE_GTYPE_A

		MOV	EDX,[ESI]._CV_LTYPE_CIRC_CNT
		JC	L5$

		MOV	[ESI]._CV_LTYPE_WORD4,AX
L9$:
		RET

L4$:
		MOV	EAX,CV_LTYPE_STRUCT._CV_LTYPE_WORD1
		MOV	ECX,1

		MOV	[ESI]._CV_LTYPE_CIRC1,EAX
		MOV	[ESI]._CV_LTYPE_CIRC_CNT,ECX

		MOV	EAX,DPTR [ESI]._CV_LTYPE_WORD3
		JMP	L2$

L5$:
		MOV	EAX,CV_LTYPE_STRUCT._CV_LTYPE_WORD4

		MOV	[ESI+EDX*4]._CV_LTYPE_CIRC1,EAX
		INC	EDX

		MOV	[ESI]._CV_LTYPE_CIRC_CNT,EDX

		RET

LTYPE_TYPE_2_8	ENDP


LTYPE_TYPE_V12	PROC	NEAR
		;
		;
		;
		MOV	EAX,DPTR [ESI]._CV_LTYPE_WORD5

		CMP	EAX,10000000H
		JB	L9$

		SHR	EAX,16
		CALL	CONVERT_CV_LTYPE_GTYPE_A

		MOV	EDX,[ESI]._CV_LTYPE_CIRC_CNT
		JC	L5$

		MOV	[ESI]._CV_LTYPE_WORD6,AX
L9$:
		RET

L5$:
		MOV	EAX,CV_LTYPE_STRUCT._CV_LTYPE_WORD6

		MOV	[ESI+EDX*4]._CV_LTYPE_CIRC1,EAX
		INC	EDX

		MOV	[ESI]._CV_LTYPE_CIRC_CNT,EDX

		RET

LTYPE_TYPE_V12	ENDP


LTYPE_REFSYM	PROC	NEAR
		;
		;
		;
		MOV	AL,0
		push	EAX
		call	_err_abort

LTYPE_REFSYM	ENDP


INSTALL_GTYPE_POINTER	PROC
		;
		;EAX IS POINTER, RETURN GINDEX #
		;
		PUSH	EDX
		MOV	EDX,CV_GTYPE_GARRAY._STD_LIMIT

		SHR	EDX,PAGE_BITS-2
		PUSH	ECX

		MOV	ECX,CV_GTYPE_GARRAY._STD_LIMIT

		MOV	EDX,CV_GTYPE_GARRAY[EDX*4]._STD_PTRS
		AND	ECX,PAGE_MASK SHR 2

		TEST	EDX,EDX
		JZ	L3$
L4$:
		MOV	[EDX+ECX*4],EAX
		MOV	EAX,CV_GTYPE_GARRAY._STD_LIMIT

		POP	ECX
		INC	EAX

		POP	EDX
		MOV	CV_GTYPE_GARRAY._STD_LIMIT,EAX

		CMP	EAX,64K - 1000H
		JA	L9$

		RET

L3$:
		MOV	EDX,CV_GTYPE_GARRAY._STD_LIMIT
		PUSH	EAX

		SHR	EDX,PAGE_BITS-2
		CALL	GET_NEW_LOG_BLK

		MOV	CV_GTYPE_GARRAY[EDX*4]._STD_PTRS,EAX
		MOV	EDX,EAX

		POP	EAX
		JMP	L4$

L9$:
		MOV	AX,CVP_GTYPES_64K_ERR
		push	EAX
		call	_err_abort

INSTALL_GTYPE_POINTER	ENDP


		.CONST

		ALIGN	4

LTYPE_DEFINES	LABEL	DWORD

		DD	LTYPE_NO_TYPES		;LF_UNDEFINED
		DD	LTYPE_TYPE_4		;LF_MODIFIER, TYPE AT OFFSET 4
		DD	LTYPE_POINTER		;LF_POINTER, SPECIAL CASE
		DD	LTYPE_TYPE_2_4		;LF_ARRAY, TYPES AT OFFSET 2 AND 4
		DD	LTYPE_TYPE_4_10		;LF_CLASS, TYPES AT OFFSET 4 AND 10
		DD	LTYPE_TYPE_4_10		;LF_STRUCTURE, TYPES AT OFFSET 4 AND 10
		DD	LTYPE_TYPE_4		;LF_UNION, TYPE AT OFFSET 4
		DD	LTYPE_TYPE_4_6		;LF_ENUMERATION, TYPES AT OFFSET 4 AND 6
		DD	LTYPE_TYPE_2_8		;LF_PROCEDURE
		DD	LTYPE_TYPE_2_4_6_12	;LF_MFUNCTION
		DD	LTYPE_NO_TYPES		;LF_VTSHAPE
		DD	LTYPE_TYPE_2		;LF_COBOL0
		DD	LTYPE_NO_TYPES		;LF_COBOL1
		DD	LTYPE_TYPE_2		;LF_BARRAY
		DD	LTYPE_NO_TYPES		;LF_LABEL
		DD	LTYPE_NO_TYPES		;LF_NULL
		DD	LTYPE_NO_TYPES		;LF_NOTTRANS
		DD	LTYPE_TYPE_2_4		;LF_DIMARRAY
		DD	LTYPE_ARGLIST		;LF_VFTPATH, SAME AS ARGLIST
		DD	LTYPE_NO_TYPES		;LF_PRECOMP
		DD	LTYPE_NO_TYPES		;LF_ENDPRECOMP
		DD	LTYPE_OEM		;LF_OEM
		DD	LTYPE_NO_TYPES		;LF_RESERVED
		DD	LTYPE_NO_TYPES		;LF_SKIP
		DD	LTYPE_ARGLIST		;LF_ARGLIST
		DD	LTYPE_TYPE_2		;LF_DEFARG
		DD	LTYPE_NO_TYPES		;LF_LIST
		DD	LTYPE_FIELDLIST		;LF_FIELDLIST
		DD	LTYPE_NO_TYPES		;LF_DERIVED
		DD	LTYPE_TYPE_4		;LF_BITFIELD
		DD	LTYPE_MLIST		;LF_MLIST
		DD	LTYPE_TYPE_4		;LF_DIMCONU
		DD	LTYPE_TYPE_4		;LF_DIMCONLU
		DD	LTYPE_DIMVARU		;LF_DIMVARU
		DD	LTYPE_DIMVARU		;LF_DIMVARLU
		DD	LTYPE_REFSYM		;LF_REFSYM
		DD	LTYPE_TYPE_2		;LF_BCLASS
		DD	LTYPE_TYPE_2_4		;LF_VBCLASS
		DD	LTYPE_TYPE_2_4		;LF_IVBCLASS
		DD	LTYPE_NO_TYPES		;LF_ENUMERATE
		DD	LTYPE_TYPE_2		;LF_FRIENDFCN
		DD	LTYPE_TYPE_2		;LF_INDEX, CANT HAPPEN, ...
		DD	LTYPE_TYPE_2		;LF_MEMBER
		DD	LTYPE_TYPE_2		;LF_STMEMBER
		DD	LTYPE_TYPE_4		;LF_METHOD
		DD	LTYPE_TYPE_2		;LF_NESTEDTYPE
		DD	LTYPE_TYPE_2		;LF_VFUNCTAB
		DD	LTYPE_TYPE_2		;LF_FRIENDCLS
		DD	LTYPE_TYPE_4		;LF_ONEMETHOD
		DD	LTYPE_TYPE_2		;LF_VFUNCOFF


		ALIGN	4

SUBTYPE_TBL	LABEL	DWORD

		DD	SUB_BCLASS
		DD	SUB_VBCLASS
		DD	SUB_VBCLASS			;IVBCLASS
		DD	SUB_ENUMERATE
		DD	SUB_FRIENDFCN
		DD	SUB_BCLASS			;LF_INDEX, CANNOT HAPPEN
		DD	SUB_MEMBER
		DD	SUB_STMEMBER
		DD	SUB_METHOD
		DD	SUB_FRIENDFCN			;LF_NESTEDTYPE
		DD	SUB_VFUNCTAB
		DD	SUB_VFUNCTAB			;LF_FRIENDCLS
		DD	SUB_ONEMETHOD
		DD	SUB_VFUNCOFF


		.DATA?

		ALIGN	4

CIRCULAR_BASE		DD	?
CIRCULAR_INDEX		DD	?
CONVERT_NEST_LEVEL	DD	?
CIRCULAR_CSUE		DD	?

XR_GTYPE_GINDEX		DD	?
LAST_XR_GTYPE_GINDEX	DD	?
DERIV_PTR		DD	?
DERIV_PTR_LIMIT		DD	?
FIRST_DERIV_BLK		DD	?

endif


		END

